package com.example.demo.connect;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;

import com.example.demo.R;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class ConnectAndDisconnectActivity extends AppCompatActivity {

    // 新增成员变量
    private BluetoothAdapter bluetoothAdapter;
    private String deviceAddress;
    private String deviceName;
    private Button start_test;
    private EditText test_time, dis_time, wait_time;

    private int pass_time,fail_time,connectOver_time,disconnectOver_time,error_time;
    private TextView textView;
    private Thread currentThread; // 用于存储当前线程
    private Handler handler = new Handler();

    private ConnectManager connectManager;

    private static final int REQUEST_CODE_CREATE_DOCUMENT = 113;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_connectanddisconnect);

        // 设置 Toolbar 作为 ActionBar
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        deviceName = getIntent().getStringExtra("bluetooth_name");
        // 存储MAC地址
        deviceAddress = getIntent().getStringExtra("bluetooth_address");
        ((TextView) findViewById(R.id.device_name)).setText("设备名称：" + deviceName + "\n" + "MAC地址：" + deviceAddress);

        // 新增初始化
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        connectManager = new ConnectManager(bluetoothAdapter, deviceAddress);
        connectManager.initProfiles(this);

        // 控件初始化
        // 开始按键
        start_test = findViewById(R.id.start_test);
        // 次数
        test_time = findViewById(R.id.test_times);
        // 断连时间
        dis_time = findViewById(R.id.dis_times);
        // 间隔时间
        wait_time = findViewById(R.id.wait_times);
        // 日志textview
        textView = findViewById(R.id.tv_log);
        textView.setText(textView.getText(), TextView.BufferType.EDITABLE);
        textView.setMovementMethod(new ScrollingMovementMethod());



        // 设置默认值
        test_time.setText("50"); // 默认测试次数
        dis_time.setText("15");   // 默认断连时间
        wait_time.setText("30");  // 默认间隔时间

        // 按钮点击事件
        start_test.setOnClickListener(v -> ConnectAndDisconnect());

        // 注册广播接收器
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        registerReceiver(bluetoothReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 终止当前线程
        if (currentThread != null && currentThread.isAlive()) {
            currentThread.interrupt();
            try {
                currentThread.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                Log.e("TEST", "线程中断", e);
            }
        }

        // 取消注册广播接收器
        unregisterReceiver(bluetoothReceiver);
    }

    private void ConnectAndDisconnect() {

        // 初始化统计计数器
        pass_time = 0;
        fail_time = 0;
        connectOver_time = 0;
        disconnectOver_time = 0;
        error_time = 0;

        if (connectManager.isConnected()) {
            //若是连接状态，则断开连接
            connectManager.disconnectDevice(() -> {
            });
        }

        // 获取测试次数
        String get_times = test_time.getText().toString().trim();
        // 获取间隔时间
        String w_time = wait_time.getText().toString().trim();
        // 获取断连时间
        String d_time = dis_time.getText().toString().trim();

        if (!get_times.isEmpty()) {
            try {
                // 验证并解析测试次数，如果未提供，则使用默认值
                int g_times = validateInput(get_times, "测试次数", 50); // 默认值为50次
                // 验证并解析断开时间，如果未提供，则使用默认值
                int dc_time = validateInput(d_time, "断连时间", 15) * 1000; // 默认值为15秒
                // 验证并解析间隔时间，如果未提供，则使用默认值
                int wa_time = validateInput(w_time, "间隔时间", 30) * 1000; // 默认值为30秒

                // 终止旧线程
                stopCurrentThread();


                // 开启新线程
                currentThread = new Thread(() -> {
                    textView.setText("");
                    scrollToTop();

                    for (int i = 1; i <= g_times; i++) {
                        final int currentIteration = i;

                        // 更新UI
                        updateUI(currentIteration, g_times);

                        // 等到断连的时间
                        int wat_time = wa_time - dc_time;

                        // 尝试连接设备
                        runOnUiThread(() -> connectManager.connectDevice(() -> {
                            // 持续检查连接状态
                            checkConnectStatus(dc_time);

                            if (connectManager.isConnected()) {
                                // 启动定时任务持续检测连接状态
                                startConnectionMonitor(dc_time, wat_time);
                            } else {
                                logAndAppend("连接失败，跳过断开操作", false);
                                // 记录失败次数
                                fail_time = fail_time + 1;
                            }
                        }));

                        // 等待本次连接-断开完成
                        try {
                            Thread.sleep(wa_time);
                        } catch (InterruptedException e) {
                            handleInterruptedException(e);
                        }

                        // 检查线程是否被中断
                        if (Thread.currentThread().isInterrupted()) {
                            logAndAppend("线程被中断，提前结束", false);
                            break;
                        }
                    }
                    // 测试完成后更新UI
                    runOnUiThread(() -> {
                        // 输出统计结果
                        logSummary();
                        Toast.makeText(this, "执行 " + g_times + " 次结束", Toast.LENGTH_SHORT).show();

                    });
                });
                currentThread.start();

            } catch (IllegalArgumentException e) {
                runOnUiThread(() -> {
                    Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }
        }
    }

    private void startConnectionMonitor(int dc_time, int wat_time) {
        Runnable connectionMonitor = new Runnable() {
            @Override
            public void run() {
                if (connectManager.isConnected()) {
                    // 如果连接正常，继续检测
                    handler.postDelayed(this, 500); // 每隔500毫秒检查一次
                } else {
                    // 如果连接断开，执行相应处理逻辑
                    logAndAppend( "连接在延迟断开前异常断开", false);
                    logAndAppend("设备已断开: " + deviceName, false);
                    // 记录连接在延迟断开前异常断开次数
                    error_time = error_time + 1;
                    // 取消延迟断开操作
                    handler.removeCallbacksAndMessages(null);
                    // 记录失败次数
                    fail_time = fail_time + 1;
                }
            }
        };

        // 启动定时任务
        handler.postDelayed(connectionMonitor, 500); // 初始延迟500毫秒

        // 延迟后断开
        handler.postDelayed(() -> {
            // 取消定时任务
            handler.removeCallbacks(connectionMonitor);

            if (connectManager.isConnected()) {
                connectManager.disconnectDevice(() -> {
                    // 持续检查断开状态
                    checkDisconnectStatus(wat_time);
                    // 记录成功次数
                    pass_time = pass_time + 1;
                });
            } else {
                logAndAppend( "连接在延迟断开前已断开，跳过断开操作", false);

            }
        }, dc_time);
    }

    private void checkConnectStatus(int dc_time) {
        long startTime = System.currentTimeMillis();
        while (System.currentTimeMillis() - startTime < dc_time) {
            if (connectManager.isConnected()) {
                // 记录连接结束时间
                long connectEndTime = System.currentTimeMillis();
                logAndAppend("连接成功", true);
                // 计算连接时间
                long connectDuration = connectEndTime - startTime;
                logAndAppend("设备已连接: " + deviceName, true);
                logAndAppend( "连接耗时: " + connectDuration + " ms", true);
                return;
            }
            try {
                Thread.sleep(500); // 每隔500毫秒检查一次
            } catch (InterruptedException e) {
                handleInterruptedException(e);
                return;
            }
        }
        // 记录连接结束时间
        long connectEndTime = System.currentTimeMillis();
        logAndAppend( "连接超时", false);
        // 计算连接时间
        long connectDuration = connectEndTime - startTime;
        logAndAppend("连接耗时: " + connectDuration + " ms", false);
        // 记录连接超时次数
        connectOver_time = connectOver_time + 1;
    }

    private void checkDisconnectStatus(int wat_time) {
        long startTime = System.currentTimeMillis();
        while (System.currentTimeMillis() - startTime < wat_time) {
            if (connectManager.isDisconnected()) {
                // 记录断开结束时间
                long disconnectEndTime = System.currentTimeMillis();
                logAndAppend("断开成功", true);
                // 计算断开时间
                long disconnectDuration = disconnectEndTime - startTime;
                logAndAppend("设备已断开: " + deviceName, true);
                logAndAppend( "断开耗时: " + disconnectDuration + " ms", true);
                return;
            }
            try {
                Thread.sleep(500); // 每隔500毫秒检查一次
            } catch (InterruptedException e) {
                handleInterruptedException(e);
                return;
            }
        }
        // 记录断开结束时间
        long disconnectEndTime = System.currentTimeMillis();
        logAndAppend("断连超时", false);
        // 计算断开时间
        long disconnectDuration = disconnectEndTime - startTime;
        logAndAppend( "断开耗时: " + disconnectDuration + " ms", false);
        // 记录断连超时次数
        disconnectOver_time = disconnectOver_time+ 1;
    }

    // 停止当前线程
    private void stopCurrentThread() {
        if (currentThread != null && currentThread.isAlive()) {
            currentThread.interrupt();
            try {
                currentThread.join(1000); // 等待最多1秒
            } catch (InterruptedException e) {
                handleInterruptedException(e);
            }
        }
    }

    // 输入验证方法
    private int validateInput(String input, String fieldName, int defaultValue) {
        try {
            int value = Integer.parseInt(input);
            if (value <= 0) {
                throw new IllegalArgumentException(fieldName + "必须大于0");
            }
            return value;
        } catch (NumberFormatException e) {
            Log.w("INPUT_VALIDATION", fieldName + "无效，使用默认值: " + defaultValue);
            return defaultValue;
        }
    }

    // 处理中断异常
    private void handleInterruptedException(InterruptedException e) {
        Thread.currentThread().interrupt();
        Log.e("TEST", "线程中断", e);
    }

    // 格式化日志
    private SpannableString formatLog(String message, boolean isSuccess) {
        String fullMessage = message + "\n";
        SpannableString spannableString = new SpannableString(fullMessage);
        ForegroundColorSpan colorSpan = new ForegroundColorSpan(
                isSuccess ? ContextCompat.getColor(this, R.color.custom_success_color)
                        : ContextCompat.getColor(this, R.color.custom_failure_color)
        );
        spannableString.setSpan(colorSpan, 0, fullMessage.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        return spannableString;
    }

    // 更新日志
    private void updateLog(SpannableString log) {
        runOnUiThread(() -> {
            textView.append(log);
            scrollToBottom();
        });
    }

    // 新增方法用于输出总结日志
    private void logSummary() {
        logSummaryAppend("\n\nSummary:", true);

        int totalTests = pass_time + fail_time;
        double successRate = (totalTests == 0) ? 0 : (double) pass_time / totalTests * 100;

        logSummaryAppend("      成功次数: " + pass_time, pass_time > 0);
        logSummaryAppend("      失败次数: " + fail_time, fail_time == 0);
        logSummaryAppend("      连接超时次数: " + connectOver_time, connectOver_time == 0);
        logSummaryAppend("      断开超时次数: " + disconnectOver_time, disconnectOver_time == 0);
        logSummaryAppend("      连接在延迟断开前异常断开次数: " + error_time, error_time == 0);
        logSummaryAppend(String.format("      成功率: %.2f%%", successRate), successRate == 100);


    }


    // 用于统一处理日志输出
    private void logAndAppend(String message, boolean isSuccess) {
        // 获取当前时间
        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String currentTime = sdf.format(new java.util.Date());

        // 拼接时间戳和日志消息
        String fullMessage = currentTime + " >  " + message;

        // 记录日志
        Log.d("Bluetooth", fullMessage);

        // 更新日志
        runOnUiThread(() -> updateLog(formatLog(fullMessage, isSuccess)));
    }

    // 用于统一处理总结日志输出
    private void logSummaryAppend(String message, boolean isSuccess) {


        // 拼接时间戳和日志消息
        String fullMessage = message;

        // 记录日志
        Log.d("Bluetooth", fullMessage);

        // 更新日志
        runOnUiThread(() -> updateLog(formatLog(fullMessage, isSuccess)));
    }

    private void updateUI(int i, int total_times) {
        runOnUiThread(() -> {
            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formattedDate = sdf.format(new java.util.Date());
            Editable editable = (Editable) textView.getText();
            editable.append(formattedDate + " [" + i + "/" + total_times + "]\n");
            scrollToBottom();
        });
    }

    // 日志滚动到底部方法
    private void scrollToBottom() {
        textView.post(() -> {
            int offset = textView.getLineCount() * textView.getLineHeight();
            if (offset > textView.getHeight()) {
                textView.scrollTo(0, offset - textView.getHeight());
            }
        });
    }

    // 日志滚动到顶部方法
    private void scrollToTop() {
        textView.post(() -> {
            textView.scrollTo(0, 0);
        });
    }

    // 广播接收器
    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
        @SuppressLint("MissingPermission")
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
                // 在广播接收器中调用
                runOnUiThread(() -> {
                    Log.d("Bluetooth", "设备已连接: " + deviceName);

                });
            } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
                runOnUiThread(() -> {
                    Log.d("Bluetooth", "设备已断开: " + deviceName);

                });
            }
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_export_log) {
            requestStoragePermission();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void requestStoragePermission() {
        createDocument();
    }

    /**
     * 创建文档
     *
     * 创建一个可写的文档文件，以便用户保存蓝牙日志数据
     * 通过发送一个Intent来启动文件选择界面，用户可以在该界面中选择保存位置和文件名
     */
    private void createDocument() {
        // 创建一个意图，用于启动创建文档的动作
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        // 添加类别，确保文档是可打开的
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        // 设置文档类型为纯文本
        intent.setType("text/plain");

        // 获取当前日期和时间
        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        String currentDateAndTime = sdf.format(new java.util.Date());

        // 设置文件名，包含当前日期和时间
        intent.putExtra(Intent.EXTRA_TITLE, "connect_log_" + currentDateAndTime + ".txt");

        // 启动活动，等待用户选择保存位置，请求码用于标识这个操作
        startActivityForResult(intent, REQUEST_CODE_CREATE_DOCUMENT);
    }

    /**
     * 处理活动结果回调
     * 当启动其他活动（如文件创建意图）并返回结果时，该方法被调用
     *
     * @param requestCode 请求码，表示启动活动时传递的请求码
     * @param resultCode 结果码，表示活动返回结果时的状态码
     * @param resultData 返回的意图数据，可能为null
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
        super.onActivityResult(requestCode, resultCode, resultData);
        // 检查请求码和结果码以确定是否从创建文档操作返回
        if (requestCode == REQUEST_CODE_CREATE_DOCUMENT && resultCode == RESULT_OK) {
            // 确保返回的数据意图不为空
            if (resultData != null) {
                // 获取返回的文档URI
                Uri uri = resultData.getData();
                // 将日志写入到指定的文件中
                writeLogToFile(uri);
            }
        }
    }

    private void writeLogToFile(Uri uri) {
        // 将文本视图中的日志内容转换为字符串
        String logContent = textView.getText().toString();

        try (
                // 获取内容解析器根据URI打开输出流，用于写入日志内容
                OutputStream outputStream = getContentResolver().openOutputStream(uri);
                // 创建输出流写入器，用于将日志内容写入到文件中
                OutputStreamWriter writer = new OutputStreamWriter(outputStream)
        ) {
            // 将日志内容写入到文件中
            writer.write(logContent);

            Toast.makeText(this, "日志已导出", Toast.LENGTH_SHORT).show();

        } catch (IOException e) {
            // 异常处理：打印异常信息并显示导出失败的提示信息
            e.printStackTrace();
            Toast.makeText(this, "导出日志失败:" + e, Toast.LENGTH_SHORT).show();
        }
    }



}
